\chapter{Implementaci\'on}
\subsection{Instalar LEGOS en LINUX}

Descargar si no est\'a instalado el libusb desde este lugar:
\begin{listing}[style=consola, numbers=none]
http://sourceforge.net/projects/libusb/files/libusbcompat0.1/libusbcompat0.1.4/libusbcompat-0.1.4.tar.gz.bz2
\end{listing}

Descomprimir el archivo, en ese lugar ingresar los siguientes comandos
\begin{listing}[style=consola, numbers=none]
$./configure
$ make
$ sudo make install
\end{listing}

Si nos da error entrar a \url{libusb.org} e instalar la versi\'on m\'as reciente del libusb, con los mismos pasos.
Luego de esto  creamos el archivo  \textbf{/etc/udev/rules.d/70lego.rules} y colocamos las siguientes
l\'ineas:

\begin{listing}[style=consola, numbers=none]
# Lego NXT brick in normal  mode 
  SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="0694",
  ATTRS{idProduct}=="0002", GROUP="lego", MODE="0660"
# Lego NXT brick in firmware update mode (Atmel SAM-BA mode)
SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="03eb",
ATTRS{idProduct}=="6124", GROUP="lego", MODE="0660"
\end{listing}

Luego crear un grupo llamado lego con el siguiente comando:
\begin{listing}[style=consola, numbers=none]
$ sudo groupadd lego
\end{listing}
y agregar su usuario al grupo:
\begin{listing}[style=consola, numbers=none]
$ sudo gpasswd -a \<username\> lego
\end{listing}

Despu\'es de esto conectamos el lego al usb y en la consola escribimos:
\begin{listing}[style=consola, numbers=none]
$ lsusb
\end{listing}

Tenemos la siguiente salida:
\begin{listing}[style=consola, numbers=none]
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 002: ID 0458:003a KYE Systems Corp. (MouseSystems) NetScroll+ Mini Traveler / Genius NetScroll 120
Bus 004 Device 003: ID 04f3:0103 Elan Microelectronics Corp.
Bus 005 Device 002: ID 0694:0002 Lego Group Mindstorms NXT
\end{listing}

Donde se aprecia que reconoció nuestro robot. A partir de  este momento ya se puede comenzar a trabajar con el robot program\'andolo.

\subsection{Compilador LEGOS}
Compilador LEJOS
los programas para el robot necesitan un compilador especial que debemos descargarlo de la
p\'agina:

\url{http:\/\/sourceforget.net\/projects\/lejos\/files\/lejosNXJ\/}

Descargamos el último beta y obtenemos un archivo con la extensión .tar, lo descomprimos.
Para que podamos cargar los archivos  y que nos reconozca el usb en la carpeta que bajamos
anteriormente en consola ponemos:

\begin{listing}[style=consola, numbers=none]
$ ruta/que/bajamos/build
$ ant
\end{listing}

\subsection{Joystick}

Ahora debemos conectar el joystick a la pc y que se comuniquen correctamente. Pero no vamos a necesitar todas las funcionalidades del joystick, asi que no es necesario el uso de algunos botones. Para esto hicimos un driver en C que nos permita obtener cuando se apretan ciertos botones. El c\'odigo fuente del driver y de todo el proyecto se puede ver en el ap\'endice.
Con este c\'odigo tenemos el driver en C del joystick funcionando. Para conectar C con Java, donde va a correr el juego, usamos la libreria JNI (Java Native Interface). Esta libreria nos va a permitir comunicar el cambio de variables que se producen cuando el usuario presiona un bot\'on que es aceptado por el sistema. Para lograr esto primero creamos la clase (en Java) que va a comunicarse con las variables del archivo en C. Colocamos la parte mas importante, en el ap\'endice se puede ver el c\'odigo fuente completo.

\begin{listing}
public class Joystick extends Thread{
	...	
	public native void eventos();
	static {
		System.loadLibrary("joystick");
	}	
	...	
}
\end{listing}

Esta funci\'on llama a la libreria nativa joystick que todav\'ia no creamos. Para crear esa librer\'ia compilamos el c\'odigo anterior.

\begin{listing}[style=consola, numbers=none]
$ javac Joystick.java
\end{listing}

Esto genera el archivo Joystick.class, luego debemos generar una cabecera que es el archivo que va a servir de interface entre Java y C, esta cabecera se genera autom\'aticamente con el comando \textbf{javah}.

\begin{listing}[style=consola, numbers=none]
$ javah Joystick
\end{listing}

Este comando nos genera autom\'aticamente la siguiente salida.
\begin{listing}[language=C]
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "joy.c" 
/* Header for class Joystick */

#ifndef _Included_Joystick
#define _Included_Joystick
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Joystick
 * Method:    eventos
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_Joystick_eventos
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
\end{listing}

En este archivo colocamos en la l\'inea 3 el driver que hicimos para obtener los comandos env\'iados por el usuario.
La clase Joystick.c va a ser la que ademas de leer los comandos introducidos por el usuario atrav\'es del joystick. 

\subsection{Acceso a los atributos de un objeto}
Queremos modificar los atributos de una clase en Java atrav\'es de jni. Java soporta dos tipos de atributos:

\begin{itemize}
	\item \textbf{Atributos de instancia:} de los cuales existe uno por cada objeto que instanciemos.
	\item \textbf{Atributos de clase:} de los cuales existe uno puesto en la clase, en vez de los objetos de esa clase. Se distinguen porque llevan el modificador static.
\end{itemize}

Nuestro caso es el segundo. 
\subsubsection{Acceso a atributos de clase}
En el acceso a los atributos de clase para obtener el field ID usamos la función:
\begin{listing}[language=C, numbers=none]
jfiledID GetStaticFieldID(JNIEnv* env, jclass class, cost char* name,const char* signature);
\end{listing}
Después para acceder a los valores usamos:
\begin{listing}[language=C, numbers=none]
	...
	jclass clase = (*env)->GetObjectClass(env,obj);
	jfieldID fieldIDtime = (*env)->GetFieldID(env,clase,"time","I");
	jfieldID fieldIDvalue = (*env)->GetFieldID(env,clase,"value","S");
	jfieldID fieldIDtype = (*env)->GetFieldID(env,clase,"type","I");
	jfieldID fieldIDnumber = (*env)->GetFieldID(env,clase,"number","I");
	jfieldID fieldIDflag = (*env)->GetFieldID(env,clase,"flag","I");
	...
\end{listing}

Antes declaramos los valores que se van a corresponder con los que le vamos a pasar a estas variables declaradas en la clase de Java:
\begin{listing}[language=C, numbers=none]
	...
	jint valor1;
	jshort valor2;
	jint valor3;
	jint valor4;
	jint flag;
	...
\end{listing}

Cuando tenemos esto, le asignamos los valores que nos brinda el joystick y hacemos que los modifique en la clase Joystick.java de la siguiente manera:

\begin{listing}[language=C, numbers=none]
	...
	valor1 = jse.time;
	valor2 = jse.value;
	valor3 = (int)jse.type;
	valor4 = (int)jse.number;
	...
	(*env)->SetIntField(env,obj,fieldIDtime,valor1);
	(*env)->SetShortField(env,obj,fieldIDvalue,valor2);
	(*env)->SetIntField(env,obj,fieldIDtype,valor3);
	(*env)->SetIntField(env,obj,fieldIDnumber,valor4);
	...
\end{listing}

El c\'odigo fuente completo lo podemos ver en el ap\'endice, una vez que tenemos esto debemos generar la libreria que va a usar Java para poder comunicar el Joystick con el sistema. Para eso debemos compilar el c\'odigo generado como se muestra a continuaci\'on.

\begin{listing}[style=consola, numbers=none]
$ gcc  -o libjoystick.so -shared -Wl,-soname,libjoystick.so -I/usr/lib/jvm/java-7-openjdk-i386/include/ -I/usr/lib/jvm/java-7-openjdk-i386/include/linux/ -static -lc Joystick.c 
\end{listing}

En linux es  muy importante que se le coloque el prefijo lib delante de joystick y con el sufijo .so que es el que usa linux, para poder compilar y que nos reconozca Java la librer\'ia que generamos.
Una vez hecho esto vamos a tener un archivo \textit{libjoystick.so} en el directorio de trabajo tenemos que decirle a java donde tiene que buscar la librer\'ia, para eso pegamos estas dos lineas en la consola, siempre estando parados en el directorio de trabajo:
\begin{listing}[style=consola, numbers=none]
$ LD_LIBRARY_PATH=`pwd`
$ export LD_LIBRARY_PATH
\end{listing}

Con esto funcionando nos queda generar la clase en Java que va a ser modificada por el archivo que generamos en C.
Cuando tenemos todo el c\'odigo lo compilamos, siempre parados en el directorio de trabajo y ya descargadas las librer\'ias de lejos en el mismo path.

\begin{listing}[style=consola, numbers=none]
$ javac classpath ~/lejos/lib/pc/pccomm.jar:~/lejos/lib/pc/3rdparty/bluecove.jar:~/lejos/lib/pc/3rdparty/bluecovegpl.jar:/ruta/al/proyecto/libjoystick.so con2Ini.java SMR.java SMJ.java Ventana.java CA.java ViewManager.java Joystick.java Contenedor.java VariableChangeListener.java
\end{listing}

Correr (los .jar estan en la misma carpeta que la clase principal):
\begin{listing}[style=consola, numbers=none]
$ java cp .:./pccomm.jar:./bluecove.jar:./bluecovegpl.jar con2Ini
\end{listing}